package com.ttg.web.dao.Impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ttg.common.dto.TagProducer;
import com.ttg.common.entities.BasePage;
import com.ttg.common.enums.CouponVipStatusEnum;
import com.ttg.common.utils.DateTimeUtil;
import com.ttg.common.utils.QxAndJhUtil;
import com.ttg.model.dto.VipTagDto;
import com.ttg.model.dto.VipUpdataDto;
import com.ttg.model.dto.open.QueryVipGradeByCustomerDto;
import com.ttg.model.dto.open.QueryVipGradeByIdCardDto;
import com.ttg.model.dto.open.QueryVipTagByCustomerNoDto;
import com.ttg.model.dto.open.QueryVipTagByIdCardDto;
import com.ttg.model.mapper.VipInfoMapper;
import com.ttg.model.pojo.VipInfo;
import com.ttg.model.vo.VipGetInfoListVo;
import com.ttg.model.vo.VipInfoGetListVo;
import com.ttg.model.vo.VipTagVo;
import com.ttg.model.vo.open.QueryVipGradeByCustomerNoVo;
import com.ttg.model.vo.open.QueryVipGradeByIdCardVo;
import com.ttg.model.vo.open.QueryVipTagInfoVo;
import com.ttg.model.vo.open.VipInfoVo;
import com.ttg.web.dao.VipInfoDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author zhangHongYuan
 * @description
 * @date 2023/6/8 11:19
 */
@Slf4j
@Service
public class VipInfoDaoImpl extends ServiceImpl<VipInfoMapper, VipInfo> implements VipInfoDao {


    @Override
    public BasePage<VipInfoGetListVo> getList(BasePage<VipInfoGetListVo> page,Long vipId, String vipMobile, String name, Double grade,Integer status, LocalDate startTime, LocalDate endTime) {
        return baseMapper.getVipInfoList(page,vipId,vipMobile,name,grade,status,startTime,endTime);
    }


    @Override
    public BasePage<VipGetInfoListVo> getInfoList(BasePage<VipGetInfoListVo> page, Long vipId, String vipMobile, Integer vipStatus, List<Long> vipIds) {
        return baseMapper.getInfoList(page,vipId,vipMobile,vipStatus,vipIds);
    }

    @Override
    public boolean updateVipStatus(VipUpdataDto dto) {
        return baseMapper.updateVipStatus(dto.getVipId(),dto.getVipStatus());
    }

    @Override
    public VipTagVo getVipTag(VipTagDto dto) {
        return baseMapper.getVipTag(dto.getVipId(),dto.getIdCard(),dto.getBusinessLicense());
    }

    @Override
    public VipInfoVo getSycnVip(Long vipId) {
        return baseMapper.getSycnVip(vipId);
    }

    @Override
    public VipInfo openGetByCrdIdNo(String crdIdNo) {
        LambdaQueryWrapper<VipInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VipInfo::getVipIdCardNo,crdIdNo)
                .last("LIMIT 1");
        return getOne(wrapper);
    }

    @Override
    public List<VipInfo> allByStatus() {
        LambdaQueryWrapper<VipInfo> wrapper = new LambdaQueryWrapper<>();
//        wrapper.ne(VipInfo::getVipStatus, CouponVipStatusEnum.DELETE.getValue());
        return list(wrapper);
    }

    @Override
    public List<VipInfo> QueryByIdsAndStatus(List<Long> ids) {
        LambdaQueryWrapper<VipInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.ne(VipInfo::getVipStatus, CouponVipStatusEnum.DELETE.getValue());
        wrapper.in(VipInfo::getVipId,ids);
        return list(wrapper);
    }

    @Override
    public List<VipInfo> QueryByTimes(LocalDate localDate) {
        LambdaQueryWrapper<VipInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VipInfo::getVipGradeDate,localDate);
        wrapper.ne(VipInfo::getVipStatus, CouponVipStatusEnum.DELETE.getValue());
        return list(wrapper);
    }

    @Override
    public QueryVipTagInfoVo queryVipTagByPrivate(String idCardNo,Integer type) {
        return baseMapper.queryVipTag(idCardNo,type);
    }

    @Override
    public VipInfo getByCstId(String cstId) {
        LambdaQueryWrapper<VipInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VipInfo::getVipCstId,cstId);
        return getOne(wrapper);
    }

    @Override
    public BasePage<VipInfo> getAllByPage(BasePage basePage) {
        return page(basePage);
    }

    @Override
    public VipInfo getByCstIdSelectId(String cstId) {
        LambdaQueryWrapper<VipInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(VipInfo::getVipId);
        wrapper.eq(VipInfo::getVipCstId, cstId);
        return getOne(wrapper);
    }

    @Override
    public List<Long> getVipIdsByTags(List<TagProducer> tags, String key) {
        LambdaQueryWrapper<VipInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(VipInfo::getVipId);
        for (TagProducer tag: tags) {
            wrapper.apply(key+tag.getCompareStr()+"{0}",tag.getValue());
        }
        List<VipInfo> list = list(wrapper);
        if (Objects.isNull(list) || CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        List<Long> vipIds = list.stream().map(VipInfo::getVipId).collect(Collectors.toList());
        return list.stream().map(VipInfo::getVipId).collect(Collectors.toList());
    }

    @Override
    public List<QueryVipGradeByIdCardVo> queryVipGradeByIdCard(List<QueryVipGradeByIdCardDto> dtos, Integer typePrivate) {
        return baseMapper.queryVipGradeByIdCard(dtos,typePrivate);
    }

    @Override
    public List<QueryVipTagInfoVo> queryVipTagByIdCard(List<QueryVipTagByIdCardDto> idCardListDto, Integer typePrivate) {
        return baseMapper.queryVipTagByIdCard(idCardListDto, typePrivate);
    }

//    @Override
//    public void updateGrowByTaskIdAndDate(Long taskId, Integer nowDate, LocalDateTime nowTime) {
//        baseMapper.updateGrowByTaskIdAndDate(taskId,nowDate,nowTime);
//    }
//
//    @Override
//    public void LoadGrowBackUp() {
//        baseMapper.LoadGrowBackUp();
//    }

    @Override
    public void sumTodayIntegral(Integer excuteDate) {
        baseMapper.sumTodayIntegral(excuteDate);
    }

    @Override
    public Map<String, Long> existsMapByCtsScId(List<String> existsWhere) {
        LambdaQueryWrapper<VipInfo> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.in(VipInfo::getVipCstScId, existsWhere);
        Map<String, Long> rsMap = new HashMap<>();
        for (VipInfo vipInfo : list(lambdaQueryWrapper)) {
            rsMap.put(vipInfo.getVipCstScId(), vipInfo.getVipId());
        }
        return rsMap;
    }

    @Override
    public List<QueryVipGradeByCustomerNoVo> queryVipGradeByCustomerNo(List<QueryVipGradeByCustomerDto> customerNos, Integer typePrivate) {
        return baseMapper.queryVipGradeByCustomerNo(customerNos,typePrivate);
    }

    @Override
    public List<QueryVipTagInfoVo> queryVipTagByCustomerNo(List<QueryVipTagByCustomerNoDto> customerNos, Integer typePrivate) {
        return baseMapper.queryVipTagByCustomerNo(customerNos,typePrivate);
    }

    @Override
    public VipInfo getLastVipId() {
        LambdaQueryWrapper<VipInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(VipInfo::getVipId)
                .last("limit 1");
        return getOne(wrapper);
    }

    @Override
    public void rattingGradeByBatch(Long idStart, Long idEnd) {
        baseMapper.rattingGradeByBatch(idStart,idEnd);
    }

    @Override
    public boolean newVipRating() {
        return baseMapper.newVipRating();
    }

    @Override
    public List<VipInfo> tblGxdAppCouponVip(Integer pageSize, Long starId) {
        if (ObjectUtil.isNull(pageSize)){
            pageSize=10;
        }
        return baseMapper.tblGxdAppCouponVip(pageSize,starId);
    }

    @Override
    public Map<String, Long> existsMapByCtsId(List<String> existsWhere) {
        LambdaQueryWrapper<VipInfo> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.in(VipInfo::getVipCstId, existsWhere);
        Map<String, Long> rsMap = new HashMap<>();
        for (VipInfo vipInfo : list(lambdaQueryWrapper)) {
            rsMap.put(vipInfo.getVipCstId(), vipInfo.getVipId());
        }
        return rsMap;
    }




    @Override
    public List<VipInfo> getByIds(List<String> vipCstIds) {
        LambdaQueryWrapper<VipInfo> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.in(VipInfo::getVipCstId, vipCstIds);
        return list(lambdaQueryWrapper);
    }


    public static void xs(Object obj, String fieldName, String value) {

        // 创建一个对象
//        PrivatePrimitive myObject = new PrivatePrimitive();

        // 获取字段的Class对象
//        Class<?> clazz = myObject.getClass();
        Class<?> clazz = obj.getClass();
        // 通过字段名获取Field对象
        Field field = null;
        try {
            field = clazz.getDeclaredField(fieldName);

            // 如果字段是私有的，需要设置setAccessible(true)来绕过访问权限检查
            field.setAccessible(true);

            if (field.getType().equals(Integer.TYPE)) {
                // 如果属性是int类型，而值是String类型，尝试转换

                Integer intValue = Integer.parseInt(value);
                field.set(obj, intValue);
            }else if (field.getType().equals(Long.TYPE)){
                Long intValue = Long.parseLong(value);
                field.set(obj, intValue);
            }else if (field.getType().equals(Double.TYPE)){
                Double doubleValue = Double.parseDouble(value);
                field.set(obj, doubleValue);
            }else if (field.getType().equals(BigDecimal.class)){
                BigDecimal bigDecimalValue = new BigDecimal(value);
                field.set(obj, bigDecimalValue);
            }else if (field.getType().equals(LocalDateTime.class)){
                DateTime parse = DateUtil.parse(value);
                LocalDateTime localDate =  LocalDateTimeUtil.of(parse);
                field.set(obj, localDate);
            }else if (field.getType().equals(LocalDate.class)){
                LocalDate localDate = DateTimeUtil.parseYYYYMMDD(getYYYYMMDDDate(value));
                field.set(obj, localDate);
            }else {
                // 直接设置值，确保类型匹配
                field.set(obj, value);
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }

        System.out.println(obj);
        // 给字段赋值
//        try {
//            field.set(obj, value);
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }
    }

    public static String getYYYYMMDDDate(String date) {

//String result = date;

        String dateType = date.trim();

        dateType=dateType.replace("/", "").replace(".", "").replace("-", "").replace("年", "").replace("月", "").replace("日", "");

        return QxAndJhUtil.get8VaildDate(dateType);

    }

    public static void test1(Object o){
        Class<?> clazz = o.getClass();
        // 通过字段名获取Field对象
        Field field = null;
        try {
            field = clazz.getDeclaredField("bankCardNumber");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        // 如果字段是私有的，需要设置setAccessible(true)来绕过访问权限检查
        field.setAccessible(true);

        // 给字段赋值
        try {
            field.set(o, "新的值");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        // 打印对象，以验证字段的值已被改变
        System.out.println(o);
    }
}
